package com.hqq.concurrency.reactor;

import com.hqq.concurrency.reactor.framework.AbstractNIOChannel;
import com.hqq.concurrency.reactor.framework.ChannelHandler;
import com.hqq.concurrency.reactor.framework.NIODatagramChannel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;

import static com.hqq.concurrency.reactor.framework.NIODatagramChannel.DatagramPacket;

/**
 * LoggingHandler
 * Created by heqianqian on 2017/8/5.
 */
public class LoggingHandler implements ChannelHandler {

    private static final Logger LOGGER = LoggerFactory.getLogger(LoggingHandler.class);

    private static final byte[] ACK = "Data logged successfully".getBytes();

    @Override
    public void handleChannelRead(AbstractNIOChannel abstractNIOChannel, Object readObject, SelectionKey selectionKey) {
        if (readObject instanceof ByteBuffer) {//TCP
            doLogging((ByteBuffer) readObject);
            sendReply(abstractNIOChannel, selectionKey);
        } else if (readObject instanceof DatagramPacket) {//UDP
            DatagramPacket datagramPacket = (DatagramPacket) readObject;
            doLogging(datagramPacket.getData());
            sendReply(abstractNIOChannel, datagramPacket, selectionKey);
        } else {
            throw new IllegalStateException("Unknown data received");
        }
    }

    private void sendReply(AbstractNIOChannel abstractNIOChannel, DatagramPacket incomingPacket, SelectionKey selectionKey) {
        DatagramPacket replyPacket = new DatagramPacket(ByteBuffer.wrap(ACK));

        replyPacket.setReceiver(incomingPacket.getSender());

        abstractNIOChannel.write(replyPacket, selectionKey);
    }

    private void sendReply(AbstractNIOChannel channel, SelectionKey key) {
        ByteBuffer buffer = ByteBuffer.wrap(ACK);
        channel.write(buffer, key);
    }

    private void doLogging(ByteBuffer readObject) {
        LOGGER.info(new String(readObject.array(), 0, readObject.limit()));
    }

}
